using System;
using System.Collections.Generic;
using System.Text;

namespace Decav.Gatsb.Mobile
{
    /// <summary>
    /// Gets the content type of an <see cref="SmtpMailHeader"/>.
    /// </summary>
    [Serializable]
    public class ContentType
    {
        /// <summary>
        /// Initializes a <see cref="ContentType"/> from an SMTP
        /// content type.
        /// </summary>
        /// <param name="type">The header type.</param>
        /// <param name="boundry">The header boundry.</param>
        public ContentType(string type, string boundry)
        {
            if (type == null)
                throw new ArgumentNullException("type");

            _type = type.ToLower();
            _boundry = boundry;
        }
        
        /// <summary>
        /// Initializes a <see cref="ContentType"/> from an SMTP
        /// content type.
        /// </summary>
        /// <param name="type">The header type.</param>
        /// <param name="boundry">The header boundry.</param>
        public ContentType(string type, string boundry, string charset)
        {
            if (type == null)
                throw new ArgumentNullException("type");

            _type = type.ToLower();
            _boundry = boundry;
            _charset = charset;
        }

        private string _type;
        private string _boundry;
        private string _charset;

        /// <summary>
        /// Gets the plain text content type.
        /// </summary>
        public static readonly ContentType PlainText = new ContentType("text/plain", null);

        /// <summary>
        /// Gets the JPEG content type.
        /// </summary>
        public static readonly ContentType ImageJpeg = new ContentType("image/jpeg", null);

        /// <summary>
        /// Gets the JPG content type.
        /// </summary>
        public static readonly ContentType ImageJpg = new ContentType("image/jpg", null);

        /// <summary>
        /// Gets the GIF content type.
        /// </summary>
        public static readonly ContentType ImageGif = new ContentType("image/gif", null);

        /// <summary>
        /// Gets the mixed multipart content type.
        /// </summary>
        public static readonly ContentType MultipartMixed = new ContentType("multipart/mixed", null);

        /// <summary>
        /// Gets the type of the content, as defined in the header.
        /// </summary>
        public string Type
        {
            get
            {
                return _type;
            }
        }

        /// <summary>
        /// Gets the (optional) boundry of the content type.
        /// </summary>
        public string Boundry
        {
            get
            {
                return _boundry;
            }
        }

        /// <summary>
        /// Gets the character set that the content is in.
        /// </summary>
        public string CharacterSet
        {
            get
            {
                return _charset;
            }
        }

        /// <summary>
        /// Parses the content type from the string.
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static ContentType Parse(string data)
        {
            if (data == null)
                throw new ArgumentNullException("data");

            string[] items = data.Split(';');

            string type = items[0].Trim().ToLower();
            string boundary = null;
            string charset = null;

            if (type.StartsWith("multipart"))
            {
                for (int i = 1; i < items.Length; i++ )
                {
                    string item = items[i];
                    string[] kvpair = item.Split(new char[] { '=' }, 2);
                    string key = kvpair[0].Trim();
                    string value = kvpair[1].Trim().TrimStart('\"').TrimEnd('\"');

                    if (key == "boundary")
                        boundary = value;

                    if (key == "charset")
                        charset = value;
                }

                if (boundary == null)
                    throw new MessageParseException(string.Format("The '{0}' content type did not have a boundary defined.", type));
            }

            return new ContentType(type, boundary, charset);
        }

        public override string ToString()
        {
            return _type;
        }
    }
}
